/****************************************************************
 **版    本: 1.0
 **公    司: Lynkros Technologies (Beijing) Inc.
 **版    权: Lynkros
 **Date: 2021-01-06 16:20:56
 **LastEditTime: 2021-09-07 17:45:28
 **最后修改: Ray
 **描    述: 
 **FilePath: \4 - 副本\Source\System\inc\TypeDefine.h
*****************************************************************/
/*************************************************************************/
#ifndef __TYPEDEFINE_H
#define __TYPEDEFINE_H

#include "stdint.h"

/************************************************************************/
/*                            														*/
/************************************************************************/
// #define uint8_t unsigned char    // defined for unsigned 8-bits integer variable     无符号8位整型变量
// #define int8 signed char       // defined for signed 8-bits integer variable       有符号8位整型变量
// #define uint16_t unsigned short  // defined for unsigned 16-bits integer variable    无符号16位整型变量
// #define int16_t signed short     // defined for signed 16-bits integer variable      有符号16位整型变量
// #define uint32_t unsigned int    // defined for unsigned 32-bits integer variable    无符号32位整型变量
// #define int32 signed int       // defined for signed 32-bits integer variable      有符号32位整型变量
#define uint64 double          // defined for unsigned 64-bits integer variable    无符号64位整型变量
typedef void (*pFunction)(void);
#define STRUCT_PACKED __attribute__((packed))

#define MAXCOUNT_TIMER 64
#define MaxHistoryFrame 6
// 其他
#define Unused_Record8 0xFF        // 存储记录档未使用的标志值。8位记录
#define Unused_Record16 0xFFFF     // 存储记录档未使用的标志值。16位记录
#define Unused_Record32 0xFFFFFFFF // 存储记录档未使用的标志值。32位记录
#define TimerValue_OFF 0xFFFFFFFF  // 定时器关闭
// #define NULL 0
// #define false FALSE
// #define true TRUE



// ADC地址
#define ADC1_DR_Address ((u32)0x4001244C)

// 内部flash地址分配
#define SysCodeAddrBase 0x08000000 // 系统代码起始地址
// 时钟关闭默认值
#define Timer_Value_OFF 0xFFFFFFFF // 定时器关闭的默认时间

#define FrameHeadFlagLength 6 // 帧首长度，之前只有55 FF，但是使用485通信时发现在某些情况下55会丢，导致数据帧丢失
                              // 所以在帧首增加几个无用的字符来保证之后的有用字符有效
#define FrameEndFlagLength 2  // 帧尾无效字符



//#define BitGet(Number,pos) (Number&(0x01<<pos))
#define BitGet(Number, pos) ((Number >> pos) & 0x00000001)
#define SetBit_1(Number, pos) (Number | (0x01 << pos))
#define SetBit_0(Number, pos) (Number & (~(0x01 << pos)))
#define SetNumberBit_1(Number, pos)     \
    do                                  \
    {                                   \
        Number = SetBit_1(Number, pos); \
    } while (0)
#define SetNumberBit_0(Number, pos)     \
    do                                  \
    {                                   \
        Number = SetBit_0(Number, pos); \
    } while (0)

#define BSWAP_16(x)                        \
    (uint16_t)((((uint16_t)(x)&0x00ff) << 8) | \
             (((uint16_t)(x)&0xff00) >> 8))
#define BSWAP_32(x)                             \
    (uint32_t)((((uint32_t)(x)&0xff000000) >> 24) | \
             (((uint32_t)(x)&0x00ff0000) >> 8) |  \
             (((uint32_t)(x)&0x0000ff00) << 8) |  \
             (((uint32_t)(x)&0x000000ff) << 24))

/*
 * 把flash分成11个分区
 * 编号               名称                         起始地址            大小                      说明
 * 0        Boot_Code   0x08000000  0x00006000  启动，24K
 * 1        Sys_Code    0x08006000  0x00008000  系统，32K
 * 2        Dev0_Code   0x0800E000  0x00008000  设备0，32K
 * 3        Dev1_Code   0x08016000  0x00008000  设备1，32K
 * 4        Dev2_Code   0x0801E000  0x00006000  设备2，24K
 * 5        Dev3_Code   0x08024000  0x00006000  设备3，24K
 * 6        Dev4_Code   0x0802A000  0x00006000  设备4，24K
 * 7        Lib_Code    0x08030000  0x00006000  设备无关的库文件，24K
 * 8        PHY_Code    0x08036000  0x00006000  物理变量表，24K
 * 9        Env_Var     0x0803C000  0x00002000  配置参数，8K
 *  9.1     Dev_Set     0x0803C000  0x00000800  设备配置, 2K
 *  9.2     Dev485Info  0x0803C800  0x00000800  485从设备信息表，2K，每个4字节，最多256个从设备
 *  9.3     SubDev_Info 0x0803D000  0x00000800  分区信息，最多10个，每个0x80
 * 10       Save_Data   0x0803E000  0x00002000  数据保存，8K
 */
// 内部flash地址分配
#define Boot_Code_Addr 0x08000000 // boot代码起始地址
#define Boot_Code_Size 0x6000     // boot代码长度,24k
#define Env_Size 0x2000
#define Boot_Version    0x08005200  //boot版本号存在这里
#define Sys_Code_Addr 0x08006000 // 系统代码运行地址
#define Sys_Code_Size 0x8000     // 系统代码长度,32K

#define Dev_Code_BIG_Size 0x8000   // 设备代码长度,32K
#define Dev_Code_SMALL_Size 0x6000 // 设备代码长度,24K

#define Dev_MaxCount 5

// DEV0,32K
#define Dev0_Code_Addr 0x0800E000
// DEV1,32k
#define Dev1_Code_Addr 0x08016000
// DEV2,24K
#define Dev2_Code_Addr 0x0801E000
// DEV3,24K
#define Dev3_Code_Addr 0x08024000
// DEV4
#define Dev4_Code_Addr 0x0802A000
// Lib,24K
#define Lib_Code_Addr 0x08030000
// PHY,24K
#define PHY_Code_Addr 0x08036000
// Env,1K
#define Env_Addr 0x0803C000

#define Env_Setting_Size 0x800                        // 1K
#define SubDevInfo_Addr (Env_Addr + Env_Setting_Size) // 存储从设备信息
#define SubDevInfo_Size 0x800                         // 1K
#define Block_Info_Size 0x80                          // 每个block信息的长度，最多10个，一共2K
#define Block_Info_Addr(id) (uint32_t)(SubDevInfo_Addr + SubDevInfo_Size + Block_Info_Size * id)

#define Save_Data_Addr (uint32_t)(Env_Addr + Env_Size) // 保存数据空间
#define Save_Data_Size 0x2000                        // 8K

#define MaxFifoLength_Com1_rx 1 * 1   //
#define MaxFifoLength_Com1_tx 1 * 1   //
#define MaxFifoLength_Com2_rx 1 * 1   //
#define MaxFifoLength_Com2_tx 1 * 1   //
#define MaxFifoLength_Com3_rx 1 * 1024   //
#define MaxFifoLength_Com3_tx 2 * 1024   //
#define MaxFifoLength_Com4_rx 1 * 1   //
#define MaxFifoLength_Com4_tx 1 * 1   //
#define MaxFifoLength_Com5_rx 1 * 1   //
#define MaxFifoLength_Com5_tx 1 * 1   //
#define MaxSeqTotal 1                    // 最大分片数，主程序能处理的多分片有限
#define MaxCodeLength MaxSeqTotal * 1000 // 代码缓冲区

#define MaxSlaveDevNum 0xFE // 最大从设备个数

#define KeyDownTime 600

#define MaxSubPortLength 1000
#ifdef DEBUG
#define debug_printf(format, ...) printf(format, ##__VA_ARGS__)
#define debug_line() debug_printf("%d\n", __LINE__)
#else
#define debug_printf(format, ...) ;
#define debug_line() ;
#endif

//判断x是否是2的次方
#define is_power_of_2(x) ((x) != 0 && (((x) & ((x)-1)) == 0))
//取a和b中最小值
#define min(a, b) (((a) < (b)) ? (a) : (b))

/*定义STM32 MCU的类型*/
typedef enum
{
    STM32F0,
    STM32F1,
    STM32F2,
    STM32F3,
    STM32F4,
    STM32F7,
    STM32L0,
    STM32L1,
    STM32L4,
    STM32H7,
} MCUTypedef;

enum emFrameHeader
{
    Header_55 = 0,
    Header_FF,
    Header_FrameType,
    Header_FrameSource,
    Header_FrameLength,
    Header_Keyword = 6,
    Header_DataCheck = 10,
    Header_FrameName = 12,
    Header_FrameSeg_Total = 14,
    Header_FrameSeg_Num = 16,
    Header_End = 18,
};

enum emCOM
{
    COM1 = 0,
    COM2,
    COM3,
    COM4,
    COM5,
};

enum emCOMProtocol
{
    em232 = 0,
    em485,
};

enum emCOMMaster_slave
{
    emMaster = 0,
    emSlave,
};

// 系统工作状态
enum emSystemMode
{
    emStart = 0,        // 系统启动
    emRequestAddr = 0x100,      // 申请地址
    emRun = 0x1000,     // 运行
};

enum emRS485RWCtrl
{
    emRS485Read = 6,
    emRS485Write = 5,
};

enum emLocalCMD
{
    lCMD_beep = 1, // 蜂鸣器
    lCMD_system,   // system指令
    lCMD_restart,  // 重启
    lCMD_heartbeat,
    lCMD_write,
    lCMD_read,
    lCMD_upgrade,
    lCMD_end,
};

enum emFlashTime
{
    emFlashRun = 1000,
    emFlashRequest = 150,
};

// 电路板类型
enum emBoardType
{
    emBoardMD8, // MD8板子
    emBoardMA8, // MA8板子
    emBoardM42, // M42板子
};

// 这3个型号的设备使用相同的PCB，根据拨码来决定设备类型
enum emDeviceType
{
    emTypeB = 0,
    emTypeMD8 = 1,  //
    emTypeMA8 = 2,  //
    emTypeM38 = 3,  // BM38
    emTypeM26 = 4,  // BM26
    emTypeM42 = 5,  // BM42
    emTypeML4 = 6,  //
    emTypeML12 = 7, //
    emTypeBM50 = 8, //
    emTypeMLD6 = 9, // 6路调光照明
};

enum emDeviceVar
{
    emVarAddr,         // 地址
    emVarType,         // 类型
    emVarName,         // 设备名称
    emVarCtrl,         // 控制指令
    emVarVer,          // 版本
    emVarBeep,         // 蜂鸣器
    emVarTime,         // 时间
    emVarDelay,        // 输出延时,ms
    emVarClearAlm,     // 清除报警
    emVarCPUID,        // CPU ID
    emVarSerial,       // 串口波特率
    emVarSlave,        //
    emVarAIMode,       // AI模式，两个bit表示一个AI通道的模式，0-直流算数平均值；1-正弦波有效值；2-正弦波平均值
    emVarInfo = 0x1E,  //
    emVarPrint = 0x1F, //
    emVarDOAll = 0x20, // DO all
    emVarDIAll = 0x21, // DI all
    emVarAOAll = 0x22, // AO ALL
    emVarAIAll = 0x23, // AI ALL
    emVarBootVer = 0x0C, //Boot版本号
    emErrorCheckTime = 0x0D, //AI故障报警时间阈值
    emErrorCheckValue = 0x0E, //AI故障报警数据阈值
};
enum emFpuType
{
    emSTM32Type = 0,
    emRT5350Tpye,
    emGD32Type,
};
/*
 * 环形队列
 */
struct ring_buffer
{
    void *buffer; //缓冲区
    uint32_t size;  //大小
    uint32_t in;    //入口位置
    uint32_t out;   //出口位置
};
//版本号
typedef struct _SubModelVersion
{
    uint16_t svn;         // SVN版本号，0~65535
    uint8_t FPU_Type : 4, // 协处理器类型，0-STM32.1-RT5350.2-GD32
        DevType : 4;    // 从设备类型，
    uint8_t minor : 4,    // 次版本号
        major : 4;      // 主版本号，结构性更改时进行更新，0~15
} STRUCT_PACKED SubModeVersion_ST;
// 版本号格式 4字节
struct SemVer_ST
{
    uint16_t svn;        // SVN版本号，0~262143
    uint16_t minor : 12, // 次版本号，功能更改时进行更新，0~1023
        major : 4;     // 主版本号，结构性更改时进行更新，0~15
    /*
    之所以采用这种倒叙格式是为了兼容uint32
    因为uint32低在前，所以将SemVer直接当做uint32处理时，可以直接进行数值比较
    */
} STRUCT_PACKED;

/*--------------------------------------------------------------------------定时器类------------------------------------------------------*/
typedef struct SysTimer
{                                 //所有外设公用的定时器
    uint32_t Timer[MAXCOUNT_TIMER]; //存放所有外设的定时器的指针
    void (*Tick)();               //定时器的功能函数 需要在滴答定时器中调用此函数
    void (*Create)(uint32_t *);     //创建定时器函数
} STRUCT_PACKED SysTimer_ST;

typedef struct Led
{                       //所有外设公用的定时器
    uint32_t Flash_Time;  //闪烁时间间隔
    uint32_t Timer_Flash; //闪烁定时器
    void (*Flash)();    //定时器的功能函数 需要在滴答定时器中调用此函数
} Led_ST;

// 串口配置 20 Bytes
typedef struct _COMSet
{
    uint16_t baud; // 波特率
    uint8_t checkbit : 2,
        databit : 4,        // 数据位
        stopbit : 2;        // 停止位
    uint8_t address;          // 地址
    uint16_t CtrlPort;        // 控制端口TODO:模拟设备不需要控制端口和控制管脚，但是要在结构体里占位
    uint16_t CtrlPin;         // 控制管脚
    uint16_t fifo_id : 4,     // 使用的FIFO的id
        protocol : 4,       // 协议，0-Lynkros；1-Lynkros485；2-其它
        mode : 4,           // 端口模式，0-主。1-从
        enable_flag : 4;    // 允许标志。1-允许；0-禁止
    uint16_t fixed_delay;     // 固定延时，单位是tick
    uint16_t overtime;        // 超时，单位是tick（5ms）
    uint32_t AppName;         // 触发App名称
} STRUCT_PACKED COMSet_ST;

typedef struct _VarMap
{
    uint32_t PHYVarName;
    uint32_t APPVarName;
} STRUCT_PACKED VarMap_ST;

typedef struct _LEDConfig
{
    // GPIO_TypeDef *Port; // 端口
    uint16_t Pin;         // 管脚
    uint16_t BrightLevel; // 点亮时电平
} STRUCT_PACKED LEDConfig_ST;

// 配置参数，1024 Bytes
typedef struct _Env_ST
{
    // 系统配置，156
    uint16_t BootTime;        // boot等待时间,单位是s
    uint8_t Dev_TypeSet;      // 设备类型,2,用户设定的类型
    uint8_t Dev_TypeFix;      // 设备类型,3,通过拨码读取的类型,00-B3;01-D8;02-A8;03-BM38;04-BM26,
    uint8_t Dev_Name[16];     // 设备名称,4
    uint8_t Dev_Num;          // 运行的设备号,20
    uint8_t MasterPort;       // 主串口，每个设备只有一个主串口,21
    uint8_t MaxAddr;          // 最大分配地址号,22
    uint8_t Upgrade_flag;     // 更新标志,23
    COMSet_ST COMSet_st[5]; // 串口配置,24
    // 5个设备
    void (*Func_init_device[Dev_MaxCount])(void); // device 初始化函数,124
    struct SemVer_ST Version;                     // 版本 148
    uint32_t DODelayTime;                           // DO通道延时时间,152
    uint32_t AIMode : 24,                           // AI模式
        RefVolt : 8;                              // 参考电压,0-3.3V,1-2.5V
    uint32_t DOState;                               // DO默认状态,bit[1:0]:00-关闭,01-开启,其它-保持
    int16_t AIZero[16];                             // AI的0点
    // 设备配置
    uint8_t Reserve[320];
} STRUCT_PACKED Env_ST;
extern const Env_ST Env_st;

// 4.4 已处理通信帧管理队列结构体
typedef struct HistoryFrame
{
    uint8_t id;
    uint8_t FrameType;
    uint16_t FrameName;                      // 帧名称
    uint16_t FrameSeg_Num;                   // 分片号
} __attribute__((packed)) HistoryFrame_ST; // 已处理通信帧管理队列结构体

// 0.5 变量类型结构体
typedef struct VType
{
    uint8_t DataForm;                 // 数据格式
    uint8_t Type;                     // 设备类型
} __attribute__((packed)) VType_ST; // 用来描述变量类型的结构体

typedef struct DataDiscrp
{                      //数据定义帧 数据描述
    uint32_t NeibFlag;   //邻域标志
    uint32_t DataLength; //数据总长度
    uint16_t Step;       //计算步骤
    uint16_t State;      //状态
} __attribute__((packed)) DataDiscrp_ST;

typedef struct DataDiscrpDR
{                      //数据结果帧 数据描述
    uint32_t NeibFlag;   //邻域标志
    uint32_t DataLength; //数据总长度
    uint16_t Step;       //计算步骤
    uint16_t State;      //状态
    uint32_t UpdateTime; //更新时间
} DataDiscrpDR_ST;

// 0.3 变量/ 函数所属结构体
typedef struct VarFunc_Subjectto
{
    uint32_t AppName;                             // 变量或函数所属APP的名称
    uint32_t TaskName;                            // 变量或函数所属任务的名称
    uint32_t EventName;                           // 变量或函数所属事件的名称
} __attribute__((packed)) VarFunc_Subjectto_ST; // 说明变量或函数属于那个APP ，任务，或事件

// 0.7 变量描述结构体
typedef struct VarDescription
{
    uint32_t VarName;    // 变量名称
    uint32_t ByteLength; // 变量字节长度
    union VT
    {
        uint16_t VarType;                      // 变量类型
        VType_ST VType_st;                   // 变量类型结构体，变量类型，数据格式
    } __attribute__((packed)) VType_un;      // 变量类型联合体
    uint16_t Reserve;                          // 保留字段
} __attribute__((packed)) VarDescription_ST; // 用来描述变量的名称，类型，字节长度

typedef struct _UpgradeCode
{
    VarFunc_Subjectto_ST Var_Subjectto_st; //  变量所属App，任务，事件结构体
    uint16_t Reserve;                        // 保留字段
    uint16_t VarAmount;                      // 本通信帧中包含的变量个数
    VarDescription_ST VarDescription_st[]; // 变量描述结构体
} __attribute__((packed)) UpgradeCode_ST;  // 说明调试协议中变量数据帧结构

// 3.0 帧头结构体
typedef struct FrameHead
{
    uint8_t FrameType;                    // 帧类型
    uint8_t SourceType;                   // 发送源说明，说明发送源端口，以及通信帧的紧急程度
    uint16_t DataLength;                  // 数据长度
    uint32_t Keyword;                     // 密码字段
    uint16_t DataCheck;                   // 数据校验
    uint16_t FrameName;                   // 帧名称
    uint16_t FrameSeg_Total;              // 总分片数
    uint16_t FrameSeg_Num;                // 本通信帧分片号
} __attribute__((packed)) FrameHead_ST; // 说明协议栈中各种通信帧通用的帧头部分结构

// 3.2.6 变量数据帧
typedef struct FrameVarData
{
    FrameHead_ST FrameHead_st;             // 帧头部分
    VarFunc_Subjectto_ST Var_Subjectto_st; // 变量所属App，任务，事件结构体
    uint16_t Reserve;                        // 保留字段
    uint16_t VarAmount;                      // 本通信帧中包含的变量个数
    VarDescription_ST VarDescription_st[]; // 变量描述结构体
    //uint8_t			Data[];						// 各个变量的数值
} __attribute__((packed)) FrameVarData_ST; // 说明调试协议中变量数据帧结构

// 升级包信息 64字节
struct Update_CPU_ST
{
    uint32_t CPN_Type;       // 目标设备类型，1：5350.0：M3
    uint8_t Name[16];        // 目标设备名称，
    uint8_t FactoryName[16]; // 厂商名称
    uint32_t Version;        // 模块版本号
    uint32_t BuildTime;      // 模块编译时间
    uint32_t FlashAddr;      // 更新flash地址
    uint32_t DataCheck;      // bin文件的CRC校验
    uint32_t TrTotal;        // 模块总数，意思是可能升级被分多次执行。
    uint32_t TrDelay;        // 当前执行的升级模块
    uint32_t Reserve;        // 保留信息
    uint8_t *Data;           // 获取bin文件的指令
} STRUCT_PACKED;

// 变量表结构体
typedef struct _tTable
{
    uint32_t *reg; // 要生成的变量表地址
    uint32_t size; // 要生成的变量表长度
    uint32_t type; // 要生成的变量表类型
} PHYVar_Table_ST;

// 0.8 变量描述完全结构体
typedef struct VarDescription_l
{
    uint32_t VarName;    // 变量名称
    uint32_t ByteLength; // 变量字节长度
    union VType_U
    {
        uint16_t VarType;                        // 变量类型
        VType_ST VType_st;                     // 变量类型结构体，变量类型，数据格式
    } __attribute__((packed)) VType_un;        // 变量类型联合体
    uint16_t Reserve;                            // 保留字段
    uint32_t EffeciveTime;                       // 变量有效时间
} __attribute__((packed)) VarDescription_l_ST; // 用来描述变量的名称，类型，字节长度

// 0.8 变量描述完全结构体
typedef struct VarDescription_2
{
    uint32_t VarName;    // 变量名称
    uint32_t ByteLength; // 变量字节长度
    union
    {
        uint16_t VarType;                  // 变量类型
        VType_ST VType_st;               // 变量类型结构体，变量类型，数据格式
    } __attribute__((packed)) VType_un;  // 变量类型联合体
    uint16_t Reserve;                      // 保留字段
    uint8_t DevVarName;                    // 设备变量名，子设备的变量名，0x20~0xFF
    uint8_t DevID;                         // 设备编号,同类型设备中的编号
    uint8_t DevType;                       // 设备类型,D8-0x01,A8-0x02,BM38-0x03,BM26-0x04
    uint8_t FlagSave : 1,                  // 是否要存储
        FlagRecIgnore : 1,               // 接收时是否忽略 1-忽略 0-不忽略
        FlagRecFunc : 1,                 // 接收到变量后是否要调用接收回调函数 1-调用 0-不调用
        Flag_UpdateA20 : 1,              // 变量是否要往A20更新标志
        Flag_Other : 3, Flag_Enable : 1; // 允许标志
    /*
    uint8_t SignalType;         // 变量ADIO外设类型
    uint8_t DeltaV;             // 变量ADIO外设变化阈值   *100
    uint8_t ErrorCode;          // 错误编码
    uint8_t Other;              // 其他
    float SignalRangeUp;      // 变量ADIO外设上限
    float SignalRangeDown;    // 变量ADIO外设下限
    */
} __attribute__((packed)) VarDescription_2_ST; // 用来描述变量的名称，类型，字节长度

// 变量表结构
typedef struct VarManager_Table
{
    uint32_t CPNType;      // 设备类型
    uint32_t VarAmount;    // 变量个数
    uint32_t MaxVarAmount; // 最大变量个数
    uint32_t Reserve;
    VarDescription_2_ST VarDescription_ST[];
} __attribute__((packed)) VarManager_Table_ST;

typedef struct Coprocessor
{ //协处理器信息
    uint8_t CPU_ID;
    uint8_t UpdateFlag;
    uint32_t Version;
    uint32_t Time;
    uint8_t Name[16];
    uint8_t Other[102];
} __attribute__((packed)) Coprocessor_ST;

// 3.2.7 变量定义帧
typedef struct FrameVarDefine
{
    FrameHead_ST FrameHead_st; // 帧头部分
                               //    InfVarDefine_ST   InfVarDefine_st;            // 变量定义通用结构体
    VarFunc_Subjectto_ST Var_Subjectto_st;
    uint16_t Reserve;
    uint16_t VarAmount;
    VarDescription_l_ST VarDescription_l_st[];
    //uint8_t         Data[];                     // 各个变量的数值
} __attribute__((packed)) FrameVarDefine_ST; // 说明调试协议中变量定义帧结构

// 3.1.1 确认帧结构体
typedef struct FrameACK
{
    FrameHead_ST FrameHead_st;         // 帧头部分
    uint8_t Port_src;                    // 接收端口号
    uint8_t Reserve;                     // 保留字段
    uint16_t FrameName_src;              // 被确认帧名称
    uint16_t FrameSeg_Num_src;           // 被确认帧分片号
} __attribute__((packed)) FrameACK_ST; // 说明协议栈中大部分协议通用的确认帧的结构体

struct LocalVarDescription_ST
{
    uint32_t var_name;
    uint16_t var_length;
    union
    {
        uint16_t VarType;                 // 变量类型
        VType_ST VType_st;              // 变量类型结构体，变量类型，数据格式
    } __attribute__((packed)) VType_un; // 变量类型联合体
};

struct GeneralFrame_ST
{
    FrameHead_ST FrameHead_st; // 帧头部分
    uint8_t data[];
};

struct LocalFrameDate_ST
{
    uint8_t type;
    uint8_t var_amount;
    uint8_t source;
    uint8_t dest;
    struct LocalVarDescription_ST LocalVarDescription_st[];
};

struct RS485_VarName_ST
{
    uint8_t VarName;   // 变量名称
    uint8_t dCOMx : 4, // 主设备com号
        sCOMx : 4;   // 子设备com号
    uint8_t COMAddr;   // 目标地址,0-主设备；1~127-从设备，255-广播
    uint8_t Reserved;
};

struct RS485_VarCtrl_ST
{
    uint8_t COMx;
    uint8_t RWctrl;
    uint16_t Reserved;
};

struct RS485_Ctrl_ST
{
    uint32_t mask : 4,    // 校验
        reserved : 20,  // 保留
        DoDelayTime:4, // DO延时，DoDelayTime*20+5
        ClearAlarm : 2, // 报警;mask=1
        restore : 1,    // 恢复出厂，1-恢复出厂;mask=0
        rst : 1;        // 重启，1-重启;mask=0
};

// App485触发帧数据格式
typedef struct _App485ActionData
{
    uint32_t VarName;
    uint16_t ByteLength;
    union
    {
        uint16_t VarType;                 // 变量类型
        VType_ST VType_st;              // 变量类型结构体，变量类型，数据格式
    } __attribute__((packed)) VType_un; // 变量类型联合体
    uint8_t FlagRW;                       // 读写标志。0-读；1-写；
    uint8_t FlagDest;                     // 目标标志。0-子设备；1-用户
    uint8_t FlagPrint;                    // 输出标志。0-不输出；1-输出
    uint8_t Reserved;                     // 保留
    uint8_t Data[];                       // 数据
} __attribute__((packed)) App485ActionData_ST;

// App485数据帧数据格式
typedef struct _App485Data
{
    uint8_t FlagRW;    // 读写标志。0-读；1-写；
    uint8_t FlagDest;  // 目标标志。0-子设备；1-用户
    uint8_t FlagPrint; // 输出标志。0-不输出；1-输出
    uint8_t Reserved;  // 保留
    uint8_t Data[];    // 数据
} __attribute__((packed)) App485Data_ST;

// 0.1 字符串名称结构体
typedef struct StringName
{
    uint8_t Name[16];                      // 用来描述名称的字符串
} __attribute__((packed)) StringName_ST; // 用户定义的区域名称，以及用户名称都用16B 的字符串表示

struct VarInput_ST
{
    uint32_t flag;
    uint32_t length;
    uint32_t step;
} __attribute__((packed));

// 2.12 调用App
// 调用App  通用结构
typedef struct InfAppStart
{
    uint32_t AppName;                // App 名称
    StringName_ST DevloperName_st; // 开发用户名
    StringName_ST UserName_st;     // 下载用户名
    uint16_t Reserve;                // 保留字段
    uint16_t InitVarAmount;          // App 初始变量个数
    //    VarDescription_l_ST     VarDescription_l_st[];          // 变量描述结构体
} __attribute__((packed)) InfAppStart_ST; // 说明调试协议和API 中通用的调用App  功能结构

// 3.2.8 App  发起帧
typedef struct FrameAppStart
{
    FrameHead_ST FrameHead_st;              // 帧头部分
    InfAppStart_ST InfAppStart_st;          // 调用App  通用结构体
} __attribute__((packed)) FrameAppStart_ST; // 说明调试协议中App 发起帧 结构

// 从设备信息  4 bytes
typedef struct _SubDevInfo
{
    uint8_t Type;      // 子设备类型
    uint8_t Addr;      // 地址
    uint8_t dCOMx : 4, // 主设备com号
        sCOMx : 4;   // 子设备com号
    uint8_t DevID;     // 同类型设备中的编号
    //    uint32_t  time;       // 超时判断
} __attribute__((packed)) SubDevInfo_ST;

//时间结构体
typedef struct
{
    uint8_t hour;
    uint8_t min;
    uint8_t sec;
    //公历日月年周
    uint16_t w_year;
    uint8_t w_month;
    uint8_t w_date;
    uint8_t week;
} tm;

typedef struct _VarName04
{
    uint8_t FPU_Type;            // CPU类型，1为5350
    uint8_t UpdateFlag;          // 更新标志
    uint32_t FPU_Ver;            // 协处理版本号
    uint32_t Time;               // 更新时间戳，unix
    char ManufacturerName[16]; // 厂家名称,utf-8
    uint8_t other[66];
} __attribute__((packed)) VarName04_ST;
#endif
/************************************************************************
 **                           	End Of File
 *************************************************************************/
